package com.appspot.seqpop.model;

import java.io.Serializable;
import java.util.HashMap;

public class AlignmentDigest implements Serializable {

    private static final long serialVersionUID = 1L;

    private HashMap<Integer, int[]> digest;
    private int length;
    private int sequenceCount;

    private AlignmentDigest(int length, int sequenceCount) {
        this.digest = new HashMap<Integer, int[]>();
        this.length = length;
        this.sequenceCount = sequenceCount;
    }

    public static AlignmentDigest digest(Alignment alignment) {
        int length = alignment.getLength();
        int sequenceCount = alignment.getSequenceCount();
        AlignmentDigest sequence = new AlignmentDigest(length, sequenceCount);
        HashMap<Object, Integer> map = new HashMap<Object, Integer>(4);
        LOOP: for (int index = 0; index < length; index++) {
            map.clear();
            Object[] nucleotides = alignment.getElementsAt(index);
            for (Object nucleotide : nucleotides) {
                if (Sequence.GAP.equals(nucleotide)) {
                    continue LOOP;
                }
                if (map.containsKey(nucleotide)) {
                    Integer count = map.get(nucleotide) + 1;
                    map.put(nucleotide, count);
                } else {
                    map.put(nucleotide, 1);
                }
            }
            if (map.size() >= 2) {
                int[] counts = new int[map.size()];
                int countIndex = 0;
                for (Integer count : map.values()) {
                    counts[countIndex++] = count;
                }
                sequence.digest.put(index, counts);
            }
        }
        return sequence;
    }

    public int getSequenceCount() {
        return this.sequenceCount;
    }

    public int getLength() {
        return this.length;
    }

    public int getSize() {
        return this.digest.size();
    }

    public Iterable<int[]> getDigest() {
        return this.digest.values();
    }
}
